home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 April: Mac OS SDK / Dev.CD Apr 98 SDK1.toast / Development Kits (Disc 1) / QuickDraw 3D / Samples / SampleCode / BoxPaint+ - non stereo / sources / BoxPaint_texture.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-14  |  19.7 KB  |  853 lines  |  [TEXT/CWIE]

  1. /******************************************************************************
  2.  **                                                                             **
  3.  **     Module:        BoxPaint_texture.c                                         **
  4.  **                                                                          **
  5.  **                                                                          **
  6.  **     Purpose:     Code for a editable texture.                             **
  7.  **                                                                          **
  8.  **                                                                          **
  9.  **                                                                          **
  10.  **     Copyright (C) 1996-1997 Apple Computer, Inc.  All rights reserved.     **
  11.  **                                                                          **
  12.  **                                                                          **
  13.  *****************************************************************************/
  14.  
  15. #include    <QuickDraw.h>
  16. #include    <QDOffscreen.h>
  17. #include    <stdlib.h>
  18. #include    <math.h>
  19. #include    <assert.h>
  20.  
  21. #include    "QD3D.h"
  22. #include    "QD3DGroup.h"
  23. #include    "QD3DShader.h"
  24. #include    "QD3DStorage.h"
  25.  
  26. #include    "BoxPaint_texture.h"
  27. #include    "BoxPaint_utility.h"
  28.  
  29. /******************************************************************************
  30.  **                                                                             **
  31.  **                                Structures                                     **
  32.  **                                                                             **
  33.  *****************************************************************************/
  34.  
  35. struct    _texture {
  36.  
  37.     TQ3StoragePixmap fStoragePixmap;    /*    The Pixmap    */
  38.  
  39.     unsigned char    *fBuffer;            /*    The Buffer    */
  40.     unsigned long    fBufferSize;        
  41.     long            resolution;            /*    the height and width of the
  42.                                             texture in pixels    */
  43.  
  44.     PicHandle        thePict;            /*    where the current texture is    */
  45.     
  46. };
  47.  
  48. /******************************************************************************
  49.  **                                                                             **
  50.  **                                Macros                                         **
  51.  **                                                                             **
  52.  *****************************************************************************/
  53.  
  54. #define    PIXEL_TYPE            unsigned long
  55. #define    BYTES_PER_PIXEL        (sizeof(PIXEL_TYPE))
  56. #define    BITS_PER_PIXEL        (8 * BYTES_PER_PIXEL)
  57.  
  58. #define    kPixelSpacing        1.0
  59. #define    kPixelSpacingSqr    (kPixelSpacing*kPixelSpacing)
  60. #define    kMinSpacing            0.001
  61.  
  62. #define    DEFAULT_TEXTURE_RESOLUTION    128
  63.  
  64. /******************************************************************************
  65.  **                                                                             **
  66.  **                                Internal Routines                             **
  67.  **                                                                             **
  68.  *****************************************************************************/
  69.  
  70. /**************************************
  71.  **                                     **
  72.  **            GENERAL TEXTURE             **
  73.  **                                     **
  74.  **************************************/
  75.  
  76. static void    Texture_Init(
  77.     TextureHdl    theTexture);
  78.  
  79.  
  80. static void    Texture_SetPixel(
  81.     TexturePtr        theTexture,
  82.     unsigned long    column,
  83.     unsigned long    row,
  84.     PIXEL_TYPE        color);
  85.                                         
  86. static void    Texture_PaintLineRC(
  87.     TexturePtr        pTexture,
  88.     unsigned long    oldColumn,
  89.     unsigned long    oldRow,
  90.     unsigned long    newColumn,
  91.     unsigned long    newRow);
  92.  
  93.  
  94. /**************************************
  95.  **                                     **
  96.  **            Buffer Routines             **
  97.  **                                     **
  98.  **************************************/
  99.  
  100. static TQ3Status    Texture_BufferNew(
  101.     TextureHdl    theTexture);
  102.     
  103. static void            Texture_BufferDispose(
  104.     TextureHdl    theTexture);
  105.  
  106.  
  107. /**************************************
  108.  **                                     **
  109.  **            Texture Routines         **
  110.  **                                     **
  111.  **************************************/
  112.  
  113. static TQ3Status    Texture_PixmapNew(
  114.     TextureHdl    theTexture);
  115.     
  116. static void    Texture_PixmapInit(
  117.     TextureHdl    theTexture);
  118.     
  119. static void    Texture_PixmapDispose(
  120.     TextureHdl    theTexture);
  121.  
  122.  
  123.  
  124. /*===========================================================================*\
  125.  *
  126.  *    Routine:    Texture_New()
  127.  *
  128.  *    Comments:    Allocates and inititalizes memory
  129.  *
  130. \*===========================================================================*/
  131.  
  132. TextureHdl    Texture_New()
  133. {
  134.     TextureHdl theTexture = (TextureHdl)Utility_MemoryNew(sizeof(Texture));
  135.     
  136.     if (!theTexture) goto bail;
  137.     
  138.     Texture_Init(theTexture);
  139.     
  140.     if (Texture_BufferNew(theTexture) == kQ3Failure) goto bail;
  141.  
  142.     if (Texture_PixmapNew(theTexture) == kQ3Failure) goto bail;
  143.     
  144.     return theTexture;
  145.     
  146. bail:
  147.     Texture_Dispose(theTexture);
  148.     return NULL;    
  149. }
  150.  
  151.  
  152. /*===========================================================================*\
  153.  *
  154.  *    Routine:    Texture_Dispose()
  155.  *
  156.  *    Comments:    Deallocates memory
  157.  *
  158. \*===========================================================================*/
  159.  
  160. void    Texture_Dispose(TextureHdl    theTexture)
  161. {
  162.     assert(theTexture != NULL);
  163.     assert(*theTexture != NULL);
  164.  
  165.     Texture_BufferDispose(theTexture);
  166.     Texture_PixmapDispose(theTexture);
  167.     
  168.     if ( (**theTexture).thePict != NULL) {
  169.         KillPicture((**theTexture).thePict);        /*    Get rid of the Pict    */
  170.     }
  171.     
  172.     DisposeHandle((char **)theTexture);
  173.     
  174. }
  175.  
  176.  
  177.  
  178. /*===========================================================================*\
  179.  *
  180.  *    Routine:    Texture_SetResolution()
  181.  *
  182.  *    Comments:    Sets the resolution of the pixmap
  183.  *
  184. \*===========================================================================*/
  185.  
  186. TQ3Status Texture_SetResolution(TextureHdl theTexture, long    newResolution)
  187. {
  188.     TQ3Status    status = kQ3Failure;
  189.     long        savedResolution;
  190.     PicHandle    savedPict;
  191.     
  192.     assert(theTexture != NULL);
  193.     assert(*theTexture != NULL);
  194.  
  195.     savedResolution     = (**theTexture).resolution;
  196.     savedPict     = (**theTexture).thePict;
  197.  
  198.     /*
  199.     **    Get rid of the current buffer
  200.     */
  201.     Texture_BufferDispose(theTexture);
  202.  
  203.     Texture_PixmapDispose(theTexture);
  204.     
  205.     /*
  206.     **    Set the new resolution
  207.     */
  208.     (**theTexture).resolution = newResolution;
  209.     
  210.     /*
  211.     **    Grab a new texture based on the new resolution
  212.     */
  213.     Texture_BufferNew(theTexture);
  214.     
  215.     Texture_PixmapNew(theTexture);
  216.     
  217.     /*
  218.     **    Set the pict to NULL (remember that we saved it). We do this
  219.     **    because SetPict deletes existing pictures in the Texture.
  220.     */
  221.     (**theTexture).thePict = NULL;            
  222.     
  223.     if ((status = Texture_SetPict(theTexture, savedPict)) != kQ3Success)
  224.     {
  225.         (**theTexture).resolution = savedResolution;
  226.     }
  227.     
  228. bail:
  229.     return    status;
  230. }
  231.  
  232.  
  233. /*===========================================================================*\
  234.  *
  235.  *    Routine:    Texture_GetResolution()
  236.  *
  237.  *    Comments:    
  238.  *
  239. \*===========================================================================*/
  240.  
  241. long    Texture_GetResolution(TextureHdl theTexture)
  242. {
  243.     assert(theTexture != NULL);
  244.     assert(*theTexture != NULL);
  245.     
  246.     return    (**theTexture).resolution;
  247. }
  248.  
  249.  
  250. /*===========================================================================*\
  251.  *
  252.  *    Routine:    Texture_SetPict()
  253.  *
  254.  *    Comments:    Converts a PICT to a Texture.  The pixmap buffer allocated
  255.  *                for this is not disposed and is returned so it can be
  256.  *                altered during the painting process.
  257.  *
  258. \*===========================================================================*/
  259.  
  260. TQ3Status Texture_SetPict(
  261.     TextureHdl            theTexture,
  262.     PicHandle             hPict)
  263. {
  264.     TQ3Status                status;
  265.     QDErr                    err;
  266.     unsigned long             *textureMap,
  267.                              *pictMap,
  268.                             pictMapAddr,
  269.                              pictRowBytes;
  270.     register unsigned long     row,
  271.                              col;
  272.     unsigned long             width,
  273.                              height;
  274.     Rect                     rectGW;
  275.     GWorldPtr                 pGWorld;
  276.     PixMapHandle             hPixMap;
  277.     GDHandle                oldGD;
  278.     GWorldPtr                oldGW;
  279.  
  280.     assert(theTexture != NULL);
  281.     assert(*theTexture != NULL);
  282.  
  283.     status  = kQ3Failure;
  284.     pGWorld = NULL;
  285.  
  286.     /*    
  287.     **    Check to make sure all the parameters are valid
  288.     */        
  289.     
  290.     if (theTexture == NULL || (**theTexture).fBuffer == NULL || *theTexture == NULL) {
  291.         return status;
  292.     }
  293.     
  294.     
  295.     /*
  296.     **    If there already is a Pict, get rid of it
  297.     */
  298.     
  299.     if ((**theTexture).thePict != NULL)
  300.     {
  301.         DisposeHandle((char **)(**theTexture).thePict);
  302.         (**theTexture).thePict = NULL;
  303.     }
  304.     
  305.     /*
  306.     **    save current port
  307.     */
  308.     
  309.     GetGWorld(&oldGW, &oldGD);
  310.  
  311.     width  = (unsigned long) (**theTexture).resolution;
  312.     height = (unsigned long) (**theTexture).resolution;
  313.  
  314.     /*
  315.     **    Create the GWorld
  316.     */
  317.         
  318.     SetRect(&rectGW, 0, 0, (unsigned short) width, (unsigned short) height);
  319.  
  320.     err = NewGWorld(&pGWorld, BITS_PER_PIXEL, &rectGW, NULL, NULL, useTempMem);
  321.     if (err != noErr) {
  322.         return status;
  323.     }
  324.  
  325.     hPixMap = GetGWorldPixMap(pGWorld);
  326.     pictMapAddr  = (unsigned long) GetPixBaseAddr (hPixMap);
  327.     pictRowBytes = (unsigned long) (**hPixMap).rowBytes & 0x3fff;
  328.  
  329.     /*    
  330.     **    Draw the PICT into the GWorld
  331.     */    
  332.     SetGWorld(pGWorld, NULL);
  333.  
  334.     LockPixels(hPixMap);
  335.     EraseRect(&rectGW);
  336.     if(hPict)
  337.         DrawPicture(hPict, &rectGW);
  338.     
  339.     /*    
  340.     **    Copy the PICT into the texture
  341.     */    
  342.     
  343.     /* (unsigned char *) textureMap = (**theTexture).fBuffer; */
  344.     textureMap = (unsigned long *) (**theTexture).fBuffer;
  345.     for (row = 0L; row < height; row++) {
  346.         pictMap = (unsigned long *) (pictMapAddr + (pictRowBytes * row));
  347.         for (col = 0L; col < width; col++) {
  348.             *textureMap++ = (*pictMap++ | 0xff000000L);
  349.         }
  350.     }
  351.  
  352.     /*    
  353.     **    Update the object
  354.     */    
  355.     
  356.     if (Q3MemoryStorage_SetBuffer(
  357.         (**theTexture).fStoragePixmap.image,
  358.         (**theTexture).fBuffer,
  359.         (**theTexture).fBufferSize,
  360.         (**theTexture).fBufferSize) == kQ3Failure)
  361.         goto bail;
  362.                                 
  363.     (**theTexture).thePict = hPict;
  364.  
  365.     UnlockPixels(hPixMap);
  366.  
  367.     if (((**theTexture).fStoragePixmap).image == NULL) {
  368.         goto bail;
  369.     }
  370.     status = kQ3Success;
  371.  
  372. bail:
  373.  
  374.     SetGWorld(oldGW, oldGD);
  375.  
  376.     /*    
  377.     **    Free GWorld
  378.     */    
  379.     
  380.     DisposeGWorld(pGWorld);
  381.  
  382.     /*    
  383.     **    Don't dispose "buffer" so the texture can be updated the texture
  384.     **    with Q3MemoryStorage_SetBuffer later
  385.     */    
  386.     
  387.     return status;
  388. }
  389.  
  390.  
  391. /*===========================================================================*\
  392.  *
  393.  *    Routine:    Texture_SetToGroup()
  394.  *
  395.  *    Comments:    Sets a Pixmap to texture a group. If the group is already
  396.  *                texturized, the texture is replaced.
  397.  *
  398. \*===========================================================================*/
  399.  
  400. TQ3Status Texture_SetToGroup(TextureHdl theTexture, TQ3GroupObject    theGroup)
  401. {
  402.     TQ3StoragePixmap    textureImage;
  403.     TQ3TextureObject    textureObject;
  404.     TQ3GroupPosition    position;
  405.     TQ3Object            firstObject;
  406.     
  407.     assert(theTexture != NULL);
  408.     assert(*theTexture != NULL);
  409.  
  410.     textureImage = (**theTexture).fStoragePixmap;
  411.     textureObject = Q3PixmapTexture_New(&textureImage);
  412.         
  413.     /*
  414.     **    if we have a texture object
  415.     */
  416.     if( textureObject ) {
  417.         if( Q3Object_IsType(theGroup, kQ3GroupTypeDisplay) == kQ3True) {
  418.             Q3Group_GetFirstPosition(theGroup, &position);
  419.     
  420.             Q3Group_GetPositionObject(theGroup, position,    &firstObject);
  421.     
  422.             if( Q3Object_IsType(firstObject, kQ3SurfaceShaderTypeTexture) == kQ3True) {
  423.                 TQ3TextureObject    oldTextureObject;
  424.                 TQ3StoragePixmap oldTextureImage;
  425.                         
  426.                 Q3TextureShader_GetTexture(firstObject, &oldTextureObject);
  427.                 Q3PixmapTexture_GetPixmap(oldTextureObject, &oldTextureImage);
  428.                 
  429.                 Q3Object_Dispose(oldTextureObject);
  430.                 Q3TextureShader_SetTexture(firstObject, textureObject);
  431.                 Q3Object_Dispose(textureObject);
  432.  
  433.                 /*    
  434.                 **    this is assuming that no other object uses this texture
  435.                 **    any more
  436.                 */    
  437.                 Q3Object_Dispose(oldTextureImage.image);
  438.             } else {
  439.                 TQ3ShaderObject textureShader;
  440.                 
  441.                 textureShader = Q3TextureShader_New(textureObject);
  442.                 Q3Object_Dispose(textureObject);
  443.                 Q3Group_AddObjectBefore(theGroup, position, textureShader);
  444.                 Q3Object_Dispose(textureShader);
  445.             }
  446.             
  447.             Q3Object_Dispose(firstObject);
  448.         } else if( Q3Object_IsType(theGroup, kQ3DisplayGroupTypeOrdered) == kQ3True) {
  449.             TQ3ShaderObject textureShader;
  450.             
  451.             Q3Group_GetFirstPositionOfType(
  452.                 theGroup,
  453.                 kQ3ShapeTypeShader, &position);    
  454.             
  455.             if( position ) {
  456.                 Q3Group_GetPositionObject(theGroup, position,    &firstObject);
  457.     
  458.                 if( Q3Object_IsType(firstObject, kQ3SurfaceShaderTypeTexture) == kQ3True) {
  459.                     TQ3TextureObject    oldTextureObject;
  460.                     TQ3StoragePixmap oldTextureImage;
  461.                     
  462.                     Q3TextureShader_GetTexture(firstObject, &oldTextureObject);
  463.                     Q3PixmapTexture_GetPixmap(oldTextureObject, &oldTextureImage);
  464.                     
  465.                     Q3Object_Dispose(oldTextureObject);
  466.                     Q3TextureShader_SetTexture(firstObject, textureObject);
  467.                     Q3Object_Dispose(textureObject);
  468.                 } else {
  469.                     textureShader = Q3TextureShader_New(textureObject);
  470.                     if( textureShader ) {
  471.                         Q3Object_Dispose(textureObject);
  472.                         Q3Group_SetPositionObject(theGroup, position, textureShader);
  473.                         Q3Object_Dispose(textureShader);
  474.                     } else {
  475.                         return(kQ3Failure);
  476.                     }
  477.                 }
  478.             } else {
  479.                 textureShader = Q3TextureShader_New(textureObject);
  480.                 if( textureShader ) {
  481.                     Q3Object_Dispose(textureObject);
  482.                     Q3Group_AddObject(theGroup, textureShader);
  483.                     Q3Object_Dispose(textureShader);
  484.                 } else {
  485.                     return(kQ3Failure);
  486.                 }
  487.             }
  488.             
  489.         }
  490.     return(kQ3Success);
  491.     } else {
  492.         return(kQ3Failure);
  493.     }
  494. bail:
  495.     return kQ3Failure;
  496.     
  497. }
  498.  
  499.  
  500. /*===========================================================================*\
  501.  *
  502.  *    Routine:    Texture_Update()
  503.  *
  504.  *    Comments:    Updates QD3D to use the new texture in our stored memory.
  505.  *
  506. \*===========================================================================*/
  507.  
  508. TQ3Status    Texture_Update(TexturePtr theTexture)
  509. {
  510.     assert(theTexture != NULL);
  511.  
  512.     return Q3MemoryStorage_SetBuffer(
  513.         theTexture->fStoragePixmap.image,
  514.         theTexture->fBuffer,
  515.         theTexture->fBufferSize,
  516.         theTexture->fBufferSize);
  517. }
  518.  
  519.  
  520. /*===========================================================================*\
  521.  *
  522.  *    Routine:    Texture_PaintLineUV()
  523.  *
  524.  *    Comments:    Paints a line across a texture given UV coordinates
  525.  *
  526. \*===========================================================================*/
  527.  
  528. void Texture_PaintLineUV(
  529.     TexturePtr            theTexture,
  530.     TQ3Param2D            from,
  531.     TQ3Param2D            to)
  532. {
  533.     long    fromRow,    fromColumn,
  534.             toRow,        toColumn;
  535.         
  536.     assert(theTexture != NULL);
  537.  
  538.     fromColumn    = theTexture->fStoragePixmap.height * from.u;
  539.     fromRow = theTexture->fStoragePixmap.width  * (1.0 - from.v);
  540.     
  541.     toColumn = theTexture->fStoragePixmap.height * to.u;
  542.     toRow = theTexture->fStoragePixmap.width  * (1.0 - to.v);
  543.     
  544.     Texture_PaintLineRC(
  545.                     theTexture,
  546.                     fromColumn,
  547.                     fromRow,
  548.                     toColumn,
  549.                     toRow);
  550. }
  551.  
  552.  
  553. /**************************************
  554.  **                                     **
  555.  **        LOCAL, PRIVATE ROUTINES         **
  556.  **                                     **
  557.  **************************************/
  558.  
  559. /*===========================================================================*\
  560.  *
  561.  *    Routine:    Texture_Init()
  562.  *
  563.  *    Comments:    Initializer
  564.  *
  565. \*===========================================================================*/
  566.  
  567. static
  568. void        Texture_Init(TextureHdl theTexture)
  569. {
  570.     assert(theTexture != NULL);
  571.     assert(*theTexture != NULL);
  572.  
  573.     /*
  574.     **    Init the buffer
  575.     */
  576.     (**theTexture).fBuffer =        NULL;
  577.     (**theTexture).fBufferSize =    0;
  578.     
  579.     /*
  580.     **    DEFAULT_TEXTURE_RESOLUTION: the height and width of the pict
  581.     */
  582.     (**theTexture).resolution =     DEFAULT_TEXTURE_RESOLUTION;    
  583.  
  584.     /*
  585.     **    Init the Pict
  586.     */
  587.     (**theTexture).thePict =        NULL;
  588.     
  589.     /*
  590.     **    Init the Pixmap
  591.     */
  592.     Texture_PixmapInit(theTexture);
  593. }
  594.  
  595.  
  596. /*===========================================================================*\
  597.  *
  598.  *    Routine:    Texture_SetPixel()
  599.  *
  600.  *    Comments:    Sets the pixels in the texture.
  601.  *
  602. \*===========================================================================*/
  603.  
  604. static
  605. void Texture_SetPixel(    TexturePtr            pTexture,
  606.                         unsigned long        column,
  607.                         unsigned long        row,
  608.                         PIXEL_TYPE            color)
  609. {
  610.     unsigned long    rowBytes;
  611.     unsigned char    *pPixel,
  612.                     *pBufferStart,
  613.                     *pBufferEnd;
  614.  
  615.     assert(pTexture != NULL);
  616.  
  617.     /*    
  618.     **    Compute pixel in pixmap corresponding to (column,row)
  619.     */    
  620.     
  621.     rowBytes     = pTexture->fStoragePixmap.rowBytes;
  622.     pPixel       = pTexture->fBuffer + rowBytes * row + column * BYTES_PER_PIXEL;
  623.  
  624.  
  625.     /*    
  626.     **    Use these to test if the poked pixel falls within the fBuffer
  627.     */    
  628.     
  629.     pBufferStart = pTexture->fBuffer;
  630.     pBufferEnd   = pTexture->fBuffer + pTexture->fBufferSize;
  631.     
  632.     /*    
  633.     **    set the pixel
  634.     */    
  635.     
  636.     if ((pPixel >= pBufferStart)  && (pPixel < pBufferEnd)) {    
  637.         *((PIXEL_TYPE *) pPixel) = color;
  638.     }
  639.     
  640. }
  641.  
  642.  
  643. /*===========================================================================*\
  644.  *
  645.  *    Routine:    Texture_PaintLineRC()
  646.  *
  647.  *    Comments:    Paints a continuous line of pixels between (oldColumn,oldRow)
  648.  *                and (newColumn,newRow)
  649.  *
  650. \*===========================================================================*/
  651.  
  652. static
  653. void Texture_PaintLineRC(
  654.     TexturePtr            pTexture,
  655.     unsigned long        oldColumn,
  656.     unsigned long        oldRow,
  657.     unsigned long        newColumn,
  658.     unsigned long        newRow)
  659. {
  660.     unsigned long    column,
  661.                     row;
  662.     TQ3Vector2D        srcVector2D;
  663.     float            t,
  664.                     spacing,
  665.                     pixelDistSqr;
  666.  
  667.     assert(pTexture != NULL);
  668.  
  669.     srcVector2D.x = (long) newColumn - (long) oldColumn;
  670.     srcVector2D.y = (long) newRow    - (long) oldRow;
  671.  
  672.     if ((srcVector2D.x == 0.0) &&
  673.         (srcVector2D.y == 0.0)) {
  674.  
  675.         Texture_SetPixel(pTexture, newColumn, newRow, 0xFF000000);
  676.         return;
  677.     }
  678.  
  679.     /*    
  680.     **    Find distance from old to new pixel
  681.     */    
  682.         
  683.     pixelDistSqr = (srcVector2D.x * srcVector2D.x) +
  684.                    (srcVector2D.y * srcVector2D.y);
  685.  
  686.     spacing = kPixelSpacingSqr / pixelDistSqr;
  687.     if (spacing < kMinSpacing) {
  688.         spacing = kMinSpacing;
  689.     }
  690.  
  691.     for (t = 0.0; t <= 1.0; t += spacing) {
  692.  
  693.         column = oldColumn + t * srcVector2D.x;
  694.         row    = oldRow    + t * srcVector2D.y;
  695.  
  696.         Texture_SetPixel( pTexture, column, row, 0xFF000000);
  697.     }
  698. }
  699.  
  700.  
  701. /*===========================================================================*\
  702.  *
  703.  *    Routine:    Texture_BufferNew()
  704.  *
  705.  *    Comments:    Allocates memory
  706.  *
  707. \*===========================================================================*/
  708.  
  709. static
  710. TQ3Status    Texture_BufferNew(TextureHdl    theTexture)
  711. {
  712.     TQ3Status    status = kQ3Failure;
  713.     long        i,j;
  714.     
  715.     long         width = (**theTexture).resolution, height = (**theTexture).resolution;
  716.     
  717.     assert(theTexture != NULL);
  718.     assert(*theTexture != NULL);
  719.     assert((**theTexture).fBuffer == NULL);
  720.         
  721.     /*
  722.     **     Allocate a block of memory for the texture
  723.     */
  724.     (**theTexture).fBufferSize = width * height * BYTES_PER_PIXEL;
  725.     (**theTexture).fBuffer   = (unsigned char *) malloc((**theTexture).fBufferSize);
  726.     
  727.     /*    
  728.     **    Initialize the texture to white. This could be seriously optimized.
  729.     */    
  730.  
  731.     HLock((Handle)theTexture);
  732.     for(i = 0; i < width; i++)
  733.         for(j = 0; j < height; j++)
  734.             Texture_SetPixel(*theTexture, i, j, 0xFFFFFFFF);
  735.     HUnlock((Handle)theTexture);
  736.  
  737.     if ((**theTexture).fBuffer == NULL)
  738.     {
  739.         SysBeep(1);
  740.         status = kQ3Failure;
  741.         goto bail;
  742.     }
  743.  
  744.     status = kQ3Success;                    
  745. bail:
  746.  
  747.     return status;
  748.  
  749. }
  750.  
  751.  
  752. /*===========================================================================*\
  753.  *
  754.  *    Routine:    Texture_BufferDispose()
  755.  *
  756.  *    Comments:    Deallocates memory
  757.  *
  758. \*===========================================================================*/
  759.  
  760. static
  761. void    Texture_BufferDispose(TextureHdl    theTexture)
  762. {
  763.     assert(theTexture != NULL);
  764.     assert(*theTexture != NULL);
  765.  
  766.     if ((**theTexture).fBuffer != NULL)
  767.     {
  768.         free((**theTexture).fBuffer);
  769.         (**theTexture).fBuffer = NULL;
  770.     }
  771.     (**theTexture).fBufferSize = 0;
  772. }
  773.  
  774.  
  775. /*===========================================================================*\
  776.  *
  777.  *    Routine:    Texture_PixmapNew()
  778.  *
  779.  *    Comments:    Allocates memory
  780.  *
  781. \*===========================================================================*/
  782.  
  783. static
  784. TQ3Status    Texture_PixmapNew(TextureHdl    theTexture)
  785. {
  786.     assert(theTexture != NULL);
  787.     assert(*theTexture != NULL);
  788.  
  789.     Texture_PixmapInit(theTexture);
  790.     
  791.     ((**theTexture).fStoragePixmap).image = Q3MemoryStorage_NewBuffer(
  792.                             (**theTexture).fBuffer,
  793.                             (**theTexture).fBufferSize, 
  794.                             (**theTexture).fBufferSize);
  795.     return kQ3Success;
  796. }
  797.  
  798.  
  799. /*===========================================================================*\
  800.  *
  801.  *    Routine:    Texture_PixmapInit()
  802.  *
  803.  *    Comments:    Initializes the PixMap
  804.  *
  805. \*===========================================================================*/
  806.  
  807. static
  808. void        Texture_PixmapInit(TextureHdl theTexture)
  809. {
  810.     assert(theTexture != NULL);
  811.     assert(*theTexture != NULL);
  812.  
  813.     (**theTexture).fStoragePixmap.image        = NULL;
  814.     (**theTexture).fStoragePixmap.width        = (**theTexture).resolution;
  815.     (**theTexture).fStoragePixmap.height    = (**theTexture).resolution;
  816.     (**theTexture).fStoragePixmap.pixelSize    = BITS_PER_PIXEL;
  817.     (**theTexture).fStoragePixmap.rowBytes    = (**theTexture).fStoragePixmap.width * BYTES_PER_PIXEL;
  818.     (**theTexture).fStoragePixmap.pixelType    = kQ3PixelTypeRGB32;
  819.     (**theTexture).fStoragePixmap.bitOrder    = kQ3EndianBig;
  820.     (**theTexture).fStoragePixmap.byteOrder    = kQ3EndianBig;
  821.  
  822. }
  823.  
  824.  
  825.  
  826. /*===========================================================================*\
  827.  *
  828.  *    Routine:    Texture_DisposePixMap()
  829.  *
  830.  *    Comments:    Deallocates memory
  831.  *
  832. \*===========================================================================*/
  833.  
  834. static
  835. void    Texture_PixmapDispose(TextureHdl    theTexture)
  836. {
  837.     assert(theTexture != NULL);
  838.     assert(*theTexture != NULL);
  839.  
  840.     /*
  841.     **    if there is an image dispose of the storage object
  842.     */
  843.     if ((**theTexture).fStoragePixmap.image != NULL)
  844.     {
  845.         Q3Object_Dispose((**theTexture).fStoragePixmap.image);
  846.         (**theTexture).fStoragePixmap.image = NULL;
  847.     }
  848.     
  849.     
  850. }
  851.  
  852.  
  853.